﻿using System;
using System.Drawing;
using System.Data;
using System.IO;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Reflection;
using Swd05.SH.Bll;
using Swd05.SH.Interfaces;
namespace Swd05.SH.UI.Forms
{
	public partial class ScriptManager : System.Windows.Forms.Form
	{
		public ScriptManager()
		{
			InitializeComponent();
			this.Load += new EventHandler(this.ScriptManager_Load );
		}
		#region Properties
		public DataRow Row
		{
			get
			{
				ListViewItem item = null;
				DataRow r = null;
				if (this.LV.SelectedItems.Count == 1)
				{
					item = this.LV.SelectedItems[0];
					r = item.Tag as DataRow;
				}
				return r;
			}
		}
		private ListView LV
		{
			get
			{
				return this.lv;
			}
		}
		#endregion
		#region Methods
		private void RefreshCurrentItem()
		{
			ListViewItem item = null;
			DataRow r = null;
			if (this.LV.SelectedItems.Count == 1)
			{
				item = this.LV.SelectedItems[0];
				r = this.Row;

				item.Tag = this.Row;
				item.SubItems[1].Text = ((DateTime)r["Datum"]).ToShortDateString();
				item.SubItems[2].Text = r["Script"].ToString().Trim().Length == 0 ? "[   ]" : "[ x ]";
				item.ForeColor = System.Drawing.Color.DarkGreen;
			}
		}
		private void ScriptManager_Load(object sender, EventArgs e)
		{
			this.FillListView();
			this.InitializeMainMenu();
			
		}
		private void FillListView()
		{
			DataTable dt;
			ListViewItem item = null;

			dt = Facade.Instance.Load();

			if (dt != null)
			{
				foreach (DataRow r in dt.Rows)
				{
					item = new ListViewItem(new string[3]{ r["Id"].ToString(),
																		 ((DateTime)r["Datum"]).ToShortDateString(),
																		 r["Script"].ToString().Trim().Length == 0 ? "[   ]" : "[ x ]" });
					item.Tag = r;
					this.LV.Items.Add(item);
				}
			}

		}
		private void InitializeMainMenu()
		{
			this.LV.ContextMenu.Popup += new EventHandler(this.ContextMenu_Popup);
			this.File_Load.Click += new EventHandler(this.File_Load_Click);
			this.File_Save.Click += new EventHandler(this.File_Save_Click);
			this.File_Remove.Click += new EventHandler(File_Remove_Click);
			this.File_Compile.Click += new EventHandler(File_Compile_Click);
		}
		private void ContextMenu_Popup(object sender, EventArgs e)
		{
			bool valid = false;

			valid = (this.LV.SelectedItems.Count == 1);
			this.File_Load.Enabled = (valid);
			this.File_Save.Enabled = (valid);
			this.File_Remove.Enabled = (valid);
			this.File_Compile.Enabled = (valid);
		}
		private void File_Load_Click(object sender, EventArgs e)
		{
			OpenFileDialog dlg = null;
			string stream = string.Empty;
			DataRow r = null;

			dlg = new OpenFileDialog();
			dlg.InitialDirectory = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Desktop);
			dlg.Filter = "Regeldateien (*.rule)|*.rule";
			dlg.FilterIndex = 0;
			dlg.RestoreDirectory = true;
			dlg.Multiselect = false;
			dlg.AddExtension = true;
			dlg.DefaultExt = ".rule";
			dlg.ShowHelp = false;
			dlg.ShowReadOnly = false;
			dlg.Title = "Regeldatei öffnen";


			if (dlg.ShowDialog() == DialogResult.OK)
			{
				if (dlg.FileName != null && File.Exists(dlg.FileName))
				{
					using (StreamReader sr = new StreamReader(dlg.FileName, System.Text.Encoding.Default))
					{
						stream = sr.ReadToEnd();
					}

					r = this.Row;

					Facade.Instance.Commit(r["Id"].ToString(), stream);
					r["Script"] = stream;
					r.AcceptChanges();
					this.RefreshCurrentItem();
				}
			}
		}
		private void File_Save_Click(object sender, EventArgs e)
		{
			SaveFileDialog dlg = null;

			dlg = new SaveFileDialog();
			dlg.Title = "Regel speichern...";
			dlg.ShowHelp = false;
			dlg.RestoreDirectory = true;
			dlg.OverwritePrompt = true;
			dlg.FileName = string.Format("{0}.rule", this.Row["Id"].ToString());
			dlg.DefaultExt = ".rule";
			dlg.CheckPathExists = true;
			dlg.AddExtension = true;
			dlg.Filter = "Regeldatei (*.rule)|*.rule";
			dlg.FilterIndex = 1;
			dlg.InitialDirectory = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Desktop);

			if (dlg.ShowDialog(this) == DialogResult.OK)
			{
				using (StreamWriter sw = new StreamWriter(dlg.FileName, false, System.Text.Encoding.Default))
				{
					sw.Write(this.Row["Script"].ToString());
				}
			}
		}
		private void File_Compile_Click(object sender, EventArgs e)
		{
			IScriptFactory f = null;
			IScriptEngine engine = null;
			string file = string.Empty;
			string errors = string.Empty;
			string msg = string.Empty;
			
			f = Swd05.SH.Facade.Instance.Create(Source.Ram, "" );

			engine = f.Create( this );
			errors = (string)engine.GetType().InvokeMember( "Compile", BindingFlags.Default|BindingFlags.Instance|BindingFlags.NonPublic|BindingFlags.InvokeMethod, null, engine, new object[]{this.Row["Script"].ToString()});

			if (errors.Length > 0)
			{
				file = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Desktop) + string.Format("\\compile.error.{0}.log", this.Row["Id"].ToString());
				msg = string.Format(@"Kompilierung nicht erfolgreich.\r\nWeitere Information in der Datei\r\n{0}", file);
				using (StreamWriter sw = new StreamWriter(file, false, System.Text.Encoding.Default))
				{
					sw.Write(errors.ToString());
				}
			}
			else
			{
				msg = "Kompilierung erfolgreich...";
			}
			MessageBox.Show(this, msg, "Ergebnis Compilerlauf", MessageBoxButtons.OK, MessageBoxIcon.Information);
		}
		private void File_Remove_Click(object sender, EventArgs e)
		{
			Facade.Instance.Commit(this.Row["Id"].ToString(), "");
			this.Row["Script"] = "";
			this.Row.AcceptChanges();
			this.RefreshCurrentItem();
		}
		#endregion
	}
}
